import type { Next, Context } from 'koa';
import moment from 'moment';
import logger from '../utils/logger';
import { verify } from '../utils/token';
import tokenConfig from '../config/token';
import { publicAction, publicController } from '../config/auth';
import { getPermissions } from '../services/auth';

const now = moment().format('YYYY-MM-DD HH:mm:ss');

/**
 * 授权认证模块
 */
export default async function (ctx: Context, next: Next) {
    if (ctx.method === 'WEBSOCKET') {
        return next();
    }
    // 判断用户是否已登录
    if (ctx.controller !== 'auth') {
        // 从请求头获取token
        const token = ctx.header[tokenConfig.header] as string;
        if (!token) {
            ctx.fail(401, '请先进行登录');
            ctx.end();
        }
        // 校验token
        const result = verify(token);
        if (!result) {
            ctx.fail(401, '登录超时，请重新登录');
            ctx.end();
            return;
        }

        ctx.user = result;
    }

    // 如果为非公开，非登录的action，则验证用户是否有访问接口的权限
    const controllerAction = `/${ctx.controller}/${ctx.action}`;
    if (ctx.controller !== 'auth' && !publicAction.includes(controllerAction) && !publicController.includes(ctx.controller)) {
        const routes = await getPermissions(ctx.user.id || 0);
        if (routes.length === 0 || routes.indexOf(controllerAction) < 0) {
            logger.info('无权访问 ' + controllerAction + ' 接口');
            logger.info('=== 权限中间件执行 结束 ' + now + ' ===');
            ctx.fail(403, '您无权访问该接口，请联系管理员');
            ctx.end();
        }
    }
    logger.info('=== 权限中间件执行 结束 ' + now + ' ===');
    return next();
}
